import { Vector3 } from "three"
import { CqkjMap } from "../Basic/CqkjMap"
import { MapElement, MapElementOption } from "../Basic/MapElement"
import { setValue } from "../Util/common"
import { PROJECTION } from "../Util/static"

export enum PopupPosition {
  'auto', 'bottomright', 'bottom', 'bottomleft', 'right', 'top', 'left', 'topright', 'topleft' = 9
}

export interface PopupOption extends MapElementOption {
  /** 弹框内容 */
  html: HTMLElement,
  /** 小三角颜色 */
  color: string,
  /** 弹窗位置 */
  position: PopupPosition
  /** 鼠标离开关闭 */
  closeOnMouseLeave: boolean
  /** 与目标位置偏移 */
  distance:number
}

export class Popup extends MapElement<PopupOption>{

  readonly dom:HTMLDivElement
  private _anchor: Vector3 | undefined
  private _location = 5

  get show(): boolean {
    return this.option.show
  }
  set show(val: boolean) {
    setValue(this.option, 'show', val, () => {
      this.dom.style.display = val?'':'none'
    })
  }

  constructor(map:CqkjMap,option:PopupOption){
    super(map,option)
    this.dom=createDom(option.color,option.html)
    if (option.position) {
      this._updateAnchor(option.position)
    }
    if (option.closeOnMouseLeave) {
      this.dom.onmouseleave = () => {
        this.hide()
      }
    }
  }

  onBeforeViewChange(): void {
    this.dom.style.display = 'none'
  }

  onAfterViewChange(): void {
    const {map,_anchor,option,dom}=this
    const {distance,position}=option
    if (_anchor) {
      const point = map.worldToPanel(_anchor.clone())
    
      if (!position) {
        const {size} = map
        const location = Math.floor(point.y / (size.y / 3)) * 3 + Math.floor(point.x / (size.x / 3)) + 1
        this._updateAnchor(location)
      }
      if(distance){
        switch(this._location){
          case 1:
            point.x+=distance
            point.y+=distance
            break;
          case 2:
            point.y+=distance
            break;
          case 3:
            point.x-=distance
            point.y+=distance
            break;
          case 4:
            point.x+=distance
            break;
          case 6:
            point.x-=distance
            break;
          case 7:
            point.x+=distance
            point.y-=distance
            break;
  
          case 9:
            point.x-=distance
            point.y-=distance
            break;
          default:
            point.y-=distance
            break;
        }

      
      }
      dom.style.left = point.x + 'px'
      dom.style.top = point.y + 'px'
      
    }
    this.dom.style.display = ''
  }

  private _updateAnchor(id: number) {
    if (id != this._location) {
      this._location = id
      const dom = this.dom
      const anchor = dom.children.item(0) as HTMLDivElement
      switch (id) {
        case 1:
          this.dom.style.transform = "translate(0,0)"
          anchor.style.transform = 'rotate(135deg) translate(-1px,-1px)'
          anchor.style.left = "0"
          anchor.style.top = "0"
          break;
        case 2:
          this.dom.style.transform = "translate(-50%,0)"
          anchor.style.transform = 'rotate(180deg) translate(50%, 0px)'
          anchor.style.left = "50%"
          anchor.style.top = "0"
          break;
        case 3:
          this.dom.style.transform = "translate(-100%,0)"
          anchor.style.transform = 'rotate(-135deg) translate(13px, -10px)'
          anchor.style.left = "100%"
          anchor.style.top = "0"
          break;
        case 4:
          this.dom.style.transform = "translate(0,-50%)"
          anchor.style.transform = 'rotate(90deg) translate(-10px, 0px)'
          anchor.style.left = "0"
          anchor.style.top = "50%"
          break;
        case 6:
          this.dom.style.transform = "translate(-100%,-50%)"
          anchor.style.transform = 'rotate(-90deg) translate(10px, -20px)'
          anchor.style.left = "100%"
          anchor.style.top = "50%"
          break;
        case 7:
          this.dom.style.transform = "translate(0,-100%)"
          anchor.style.transform = 'rotate(45deg) translate(-13px, -16px)'
          anchor.style.left = "0%"
          anchor.style.top = "100%"
          break;
        case 9:
          this.dom.style.transform = "translate(-100%,-100%)"
          anchor.style.transform = 'rotate(-45deg) translate(2px, -25px)'
          anchor.style.left = "100%"
          anchor.style.top = "100%"
          break;
        default:
          this.dom.style.transform = "translate(-50%,-100%)"
          anchor.style.transform = 'translate(-50%,-20px)'
          anchor.style.left = "50%"
          anchor.style.top = "100%"
          break;
      }
    }

  }

  showAt(lon: number, lat: number,alt:number) {
    if (!this._anchor) {
      this.dom.style.display = 'none'
      this.map.dom.appendChild(this.dom)
    }
    this._anchor =new Vector3(PROJECTION.lonToX(lon), PROJECTION.latToY(lat),PROJECTION.altToZ(alt))
    this.onAfterViewChange()
    setTimeout(() => {
      this.dom.style.display = ''
    }, 100)

  }

  hide() {
    if (this._anchor) {
      this._anchor = undefined
      this.dom.remove()
    }
  }

  onDestroy(): void {
    this.dom.remove()
  }
  
}


function createDom(color:string,html:HTMLElement){
  const dom = document.createElement('div')
  dom.style.position = 'absolute'
  dom.style.zIndex = "100"
  dom.style.transform = "translate(-50%,-100%)"
  dom.style.padding = "10px";
  const anchor = document.createElement('div')
  anchor.style.borderLeft = '8px solid transparent'
  anchor.style.borderTop = `20px solid ${color}`
  anchor.style.borderRight = '8px solid transparent'
  anchor.style.position = 'absolute'
  anchor.style.transform = 'translate(-50%,-20px)'
  anchor.style.left = "50%"
  anchor.style.top = "100%"
  dom.appendChild(anchor)
  html.style.position = 'relative'
  dom.appendChild(html)
  return dom
}